# -*- coding: utf-8 -*- 

#########################################################################
## This is a samples controller
## - index is the default action of any application
## - user is required for authentication and authorization
## - download is for downloading files uploaded in the db (does streaming)
## - call exposes all registered services (none by default)
#########################################################################  

import os, sys, string
from pdf.reportlab.pdfgen.canvas import Canvas
from pdf.reportlab.lib.pagesizes import letter, A4
from pdf.reportlab.lib.units import cm, mm, inch, pica
from pdf.reportlab.graphics.charts.textlabels import Label
from pdf.reportlab.lib import colors 

                    #####################################################
                    ################################################M####
                    ## create string instrument position markers ####A###
                    ##################################################R##
                    ###################################################T#

templatedir = "./applications/generatePDF_fingerboard/templates/"
"""
ref. 4/4 = 32.6 ou 32.7 cm
rect(x, y, width, height, stroke=1, fill=0)
RGB Brown =(107,66,38)
RGB Purple = (135,31,120)
"""

###################################
# rule of 18, unrounded to 17.817 #
###################################
n = 17.817

#########################################
# number of position markers to create  #
#########################################
markers = 12

#######################################
# list of standard markers as indices #
#######################################
indexList = [1,3,4,6,8,10,11]

#####################
# string resources  #
#####################
sJoin = ' join at previous marker'

@auth.requires_login()
def main():
    ##################################################################################################
    # will create position markers in range of 2000 mm to 9000 mm, converted to cm (20.00 to 90.00)  #
    # dynamically printed to PDF                                                                     #
    ##################################################################################################
    #create()
    #createAll()
    #Test()
    pass

@auth.requires_login()
def Test():
    List = [32.6,21.75,21.4,23.45,73,90]
    for item in List:
        createTest(item)    
        
@auth.requires_login()
def createTest(sLenght):
    calculateOffsetFromScaleLenght(sLenght)

@auth.requires_login()    
def createAll():
    ##########################
    # generate scalelenghts  #
    ##########################
    i = 20.0
    Min = 20
    Max = 90
    for c in range(Min,Max):
        while i < Max:
            #print(i) # 
            i += 0.01    
            calculateOffsetFromScaleLenght(i)
            
            
@auth.requires_login()
def calculateOffsetFromScaleLenght(initScaleLenght):    
    offsetList = []
    offset = 0
    nScaleLenght = float(initScaleLenght)
    counter = 0
    while counter < markers:
        offset = getOffSet(nScaleLenght);
        offsetList.append(offset)
        nScaleLenght = get_nScalelenght(nScaleLenght,offset)     
        counter += 1    
    genPDF(initScaleLenght, (7.62,9.5,12.7),cm, offsetList)

def genPDF(initScaleLenght, (startLine,endLine, stringLine), measure, offsetList):
    ##################################
    # create reference to PDF object #
    ##################################
    pdf = Canvas(templatedir + str(initScaleLenght) + '.pdf', bottomup=1)
    pdf.setFont("Courier", 10)   

    ###################################
    # calculate total lenght of frets #
    ###################################
    fLenght = 0
    for item in offsetList:
        fLenght += item
    
    #####################
    # draw nut          #
    #####################
    pdf.line(startLine*measure,3*measure,endLine*measure,3*measure)
    pdf.drawString(stringLine * measure, 3*measure, str(0) + ' /nut/' + str(initScaleLenght))

    #############################################
    # if offsets are generated  (valid number)  #
    #############################################
    if len(offsetList) > 0:
        pageLenghtMax = 26
        accruedOffSet = 0
        belowMaxList = []
        ##############################
        # draw terminating rectangle #
        ##############################
        pdf.setStrokeColorRGB(0, 0, 0)
        pdf.rect(startLine*measure, 3*measure, 1.9*measure, (fLenght)*measure, stroke=1, fill=0)

        #########################
        # build up belowMaxList #
        #########################
        for o in offsetList:
            if o < pageLenghtMax:
                belowMaxList.append(o)
        ###########################
        # iterate over offsetList #
        ###########################
        for offset in offsetList:
            oIndex = offsetList.index(offset)
            ########################################
            # incremented sum of generated offsets #
            ########################################
            accruedOffSet = offset + accruedOffSet
            accruedOffsetString = offset + accruedOffSet
            ##########################################
            # standard markers in red else yellow    #
            ##########################################
            if oIndex in indexList:
                pdf.setStrokeColorRGB(0, 0, 0)
            else:
                pdf.setStrokeColorRGB(1, 1, 0)
            #####################
            # draw the markers  #
            #####################
            if accruedOffSet < pageLenghtMax:                      
                pdf.line(startLine*measure,(accruedOffSet + 3)*measure,endLine*measure,(accruedOffSet + 3)*measure)
                pdf.drawString(stringLine * measure, (accruedOffSet + 3)*measure, str(accruedOffSet))
            ########################################
            # create new page if eop is reached    #
            ########################################                             
            else: 
                pdf.showPage()
                pdf.setFont("Courier", 10) 
                #######################################################
                # restart accruedOffSet @ 0 and sraw "connect" marker #
                #######################################################
                pdf.line(startLine*measure,3*measure,endLine*measure,3*measure)
                pdf.drawString(stringLine * measure, 3*measure, sJoin)
                accruedOffSet = 0

        ##############################
        # draw terminating rectangle #
        ##############################
        pdf.setStrokeColorRGB(0, 0, 0)
        pdf.rect(startLine*measure, 3*measure, 1.9*measure, (accruedOffSet)*measure, stroke=1, fill=0)
        
        ################################
        # save the data to pdf file    #
        ################################
        pdf.save()

def get_nScalelenght(scalelenght,offset):
    newScaleLenght = 0
    if scalelenght > 0 and offset > 0:
        newScaleLenght = scalelenght - offset
    return newScaleLenght 
    
def getOffSet(scaleLenght):
    nOffset = 0
    if scaleLenght > 0:
        nOffset = scaleLenght / n
    return nOffset


def index():
    """
    example action using the internationalization operator T and flash
    rendered by views/default/index.html or views/generic.html
    """
    response.flash = T('some things should be free of cost!')
    return dict(message=T('welcome and please help your self to as many templates as you want!'))
 
@auth.requires_login()
def viewPDF():
    redirect(URL(r=request,f='applications/generatePDF_fingerboard/views/default/viewPDF')) 
    #redirect(URL('applications/generatePDF_fingerboard/views/default/viewPDF.html'))
    return dict(message=T('view pdf'))
    
@auth.requires_login()
def generatepdf():
    form = SQLFORM(db.scale)
    if form.accepts(request.vars, session):        
        response.flash = 'thank you - will now generate and download a pdf template for your violin to your computer'        
        if request.vars.scale_lenght:
            session.scale_lenght = request.vars.scale_lenght
            calculateOffsetFromScaleLenght(session.scale_lenght)
        ###########################
        # store the file in db
        fName = templatedir + session.scale_lenght
        pdfFname = fName + '.pdf'
        #htmToken = "<object data="
        #newline = "        <object data=' + fName + ' type='./applications/generatePDF_fingerboard/templates/' title='pdfTemplate viewer'>"
        #data_tag = "        <object data=' + fName + ' "
        #oFile = open('templates/viewpdf.html','r')
        #lines = oFile.readlines()
        #oFile.close()
        #for line in lines:
        #    if in pdfToken in line:
        #        sLine = string.split(line,"type=")[0]
        #redirect(URL('templates/' + pdfFname)) 

        #stream=open(pdfFname,'rb')
        #db.scale.insert(pdftemplate=db.scale.pdftemplate.store(stream,fName + '.txt'))
        #viewPDF()
    #return dict(storedfiles=storedfiles,form=form)            
    #return dict(scale=scale, scale_lenght=scale_lenght, form=form) 

    return dict(form=form)
    
def user():
    """
    exposes:
    http://..../[app]/default/user/login 
    http://..../[app]/default/user/logout
    http://..../[app]/default/user/register
    http://..../[app]/default/user/profile
    http://..../[app]/default/user/retrieve_password
    http://..../[app]/default/user/change_password
    use @auth.requires_login()
        @auth.requires_membership('group name')
        @auth.requires_permission('read','table name',record_id)
    to decorate functions that need access control
    """
    return dict(form=auth())

@auth.requires_login()
def download():
    """
    allows downloading of uploaded files
    http://..../[app]/default/download/[filename]
    """
    return response.download(request,db)


def call():
    """
    exposes services. for example:
    http://..../[app]/default/call/jsonrpc
    decorate with @services.jsonrpc the functions to expose
    supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv
    """
    session.forget()
    return service()
